import { basicForm, childrenProps, customForm, transitionProp } from "@/components/ProForm/interface";
import { isValidKey } from ".";
import i18n from "@/languages/index";
import { ColumnProps } from "@/components/ProTable/interface";
/**
 * @description 打开表单
 * @param {Number} row 行
 * @param {Number} col 列
 * @param {*} callValue 当前单元格值 reactive<customForm<User.ResUserList>>
 * @returns {void}
 * */

export function openForm<T>(formData: customForm<T>, title: string, row?: Object): void {
  // 对需要设置中英文不同宽度的进行设置
  const { labelWidth } = formData;
  if (labelWidth) {
    if (!formData.formAttrs) {
      formData.formAttrs = { labelWidth: setLabelWidth(labelWidth) };
    } else {
      formData.formAttrs.labelWidth = setLabelWidth(labelWidth);
    }
  }

  //打开弹框并设置标题
  Object.assign(formData, {
    title: transitionLanguages("title", title),
    visible: true
  });

  // 对应参数进行回填
  nextTick(() => {
    if (row !== undefined && row !== null) {
      for (let item of formData.options) {
        if (isValidKey(item.prop, row)) {
          formData.form[item.prop] = row[item.prop];
        }
      }
    }
  });
}

/**
 * @param { Array<number>} labelWidth 中英文宽度
 * @description 设置表单项是否禁用
 */
function setLabelWidth(labelWidth: Array<number>): string {
  // 如果需要中英文不同的宽度 使用不同的 labelWidth
  return (i18n.global.locale.value === "zh" ? labelWidth[0] : labelWidth[1] || labelWidth[0]) + "px";
}

/**
 * @param {basicForm} form 需要改变的表单
 * @param {Array<string>} fields 需要设置的字段
 * @param {String} type 修改的类型
 * @param {Boolean} flag 启用 false / 禁用 true
 * @description 设置表单项是否禁用
 */
export function changeFormItemStatus(
  form: basicForm,
  fields: Array<string>,
  flag = false,
  type: "disabled" | "hide" = "disabled"
) {
  let count = 0;
  for (const item of form?.options) {
    const { prop } = item;
    if (fields.length) {
      if (fields.includes(prop)) {
        if (type === "disabled") {
          if (item?.attrs) {
            item.attrs.disabled = flag;
          }
          count++;
        } else if (type === "hide") {
          item.hide = flag;
          count++;
        }
      }
      // 设置完成直接跳出循环
      if (count >= fields.length) {
        break;
      }
    } else {
      if (type === "disabled") {
        if (item?.attrs) {
          item.attrs.disabled = flag;
        }
      } else if (type === "hide") {
        item.hide = flag;
      }
    }
  }
}
/**
 * @param {Object} form 需要改变的表单
 * @param {string} code 表单中需要修改的key
 * @param {Function} api 调用的接口
 * @param {string} params 查询的参数
 * @param {Array} initDisplayField 返回参数显示和上传的参数字段
 * @description 下拉框远程搜索返回内容
 */
export async function remoteMethod<T>(
  form: basicForm,
  code: string,
  api: Function,
  params: string | T,
  initDisplayField = ["value", "id"]
): Promise<void> {
  for (let item of form.options) {
    const { prop } = item;
    // 找到对应需要远程搜索的字段
    if (prop === code) {
      if (!item.attrs) item.attrs = { loading: false };

      item.attrs.loading = true;
      try {
        const d = await api(params);
        const data = d?.records || d || [];
        item.attrs.loading = false;

        // 将值设置到下拉框内
        item.children = changeArrField(data, initDisplayField[0], initDisplayField[1]);
      } catch (error) {
        item.attrs.loading = false;
        item.children = [];
      }
      break;
    }
  }
}

/**
 * @param {String} form 需要设置的表单
 * @param {String} names 需要获取数据字典的名称 (多个以逗号隔开)
 * @param {Array}  transitionArr 需要装换的字段
 * @param {Function} db 回调方法
 * @description 将数据字典中内容设置到表单的 children 中
 */
export async function setDictionaries<T>(form: customForm<T>, code: string, transitionArr: transitionProp[] = [], db?: Function) {
  // 数据字典内容
  const data = await dictionaryListByCodes({ code });

  // 如果数据字典中一个值都没有
  if (!data) {
    db && db();
    return;
  }
  // 需要设置到表单中的内容集合
  let obj: any = {};

  // 数据字段获取的个数
  const namesLength = code.split(",").length;
  const transitionLength = transitionArr.length;

  // 当数据字典中  表单有两个或以上使用的是同一个 数据字典字段时  会 transitionLength > namesLength
  const length = namesLength > transitionLength ? namesLength : transitionLength;
  // 是否已设置完成
  let count = 0;

  // 将返回数据转换成key-value形式
  for (let item of data) {
    obj[item.key] = item.value;
  }

  if (transitionArr.length) {
    // 字段替换
    for (const item of transitionArr) {
      const { newField, oldField } = item || {};
      obj[newField] = data.find(v => v.key === oldField)?.value;
    }
  }

  // 将数据字段中内容设置到表单中
  for (let i = 0; i < form.options.length; i++) {
    const { prop } = form.options[i];
    if (obj[prop]) {
      count++;
      form.options[i].children = changeArrField(obj[prop], "dvalue");
      // 回填所有的数据字典后 跳出循环
      if (count >= length) {
        break;
      }
    }
  }

  db && db();
}
/**
 * @param {ColumnProps} columns 表格的列
 * @param {String} props 需要修改的字段 (多个以逗号隔开)
 * @param {boolean}  flag 隐藏 、显示
 * @description 修改表格中查询表单显示逻辑
 */
export const changeTableSearchForm = async (columns: ColumnProps[], props = "", flag = false) => {
  const prop = props.split(",");
  for (let item of columns) {
    let key = item.search?.key || "";
    if (prop.includes(key) && item.search) {
      item.search.hide = flag;
    }
  }
};
/**
 * @description: 设置表单中的 children中内容
 * @param {customForm} form
 * @param {FormChildrenProp} data
 * @return {*}
 */
interface FormChildrenProp {
  prop: string;
  children: childrenProps[];
}
export function setFormChildren<T>(form: customForm<T>, data: FormChildrenProp[]): void {
  let count = 0;
  for (let item of form.options) {
    for (let op of data) {
      if (item.prop === op.prop) {
        count++;
        item.children = op.children;
        if (count >= data.length) {
          return;
        }
        break;
      }
    }
  }
}
